unit uniAudioSDLMixer;

interface

uses
  sdl,
  sdl_mixer,
  uniAudio,
  Classes;

type
  { AudioSDLMixer }

  AudioSDLMixer = class(Audio)
  public
    sounds: array[0..Integer(NumSoundTypes) - 1] of PMix_Chunk;

    constructor Create;
    destructor Destroy; override;
    procedure playSound(_type: SoundType; pos: array of Single; age: Integer = 0); override;
    procedure stopMusic; override;
    procedure pauseGameMusic(temp: boolean); override;
    procedure setMusicMode(temp: SoundType); override;
    procedure setMusicVolume(temp: Single); override;
    procedure setSoundVolume(temp: Single); override;

    procedure initSound; override;
  end;


implementation

uses
  uniConfig,
  uniLog;


{ AudioSDLMixer }

constructor AudioSDLMixer.Create;
var
  _config: Config;
begin
  inherited Create;
  _config := uniConfig.instance;
  if _config.audioEnabled = true then
  begin
    initSound;
  end;
end;

destructor AudioSDLMixer.Destroy;
var
  _config: Config;
  i: Integer;
begin
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    for i := 0 to Integer(NumSoundTypes) - 1 do
    begin
      Mix_FreeChunk(sounds[i]);
    end;
  end;
  inherited;
end;

procedure AudioSDLMixer.initSound;
var
  _config: Config;
  i: Integer;
begin
  _config := uniConfig.instance;
  if Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0 then
  begin
    Log('ERROR initializing audio - AudioSDLMixer::initSound()');
    _config.setAudio(False);
  end
  else
  begin
    for i := 0 to Integer(NumSoundTypes) - 1 do
    begin
      sounds[i] := Mix_LoadWAV(PChar(fileNames[i]));
    end;
    Mix_ReserveChannels(1); // channel 0 is for music
    //    atexit(
  end;
end;

procedure AudioSDLMixer.pauseGameMusic(temp: boolean);
var
  _config: Config;
  i: Integer;
begin
  _config := uniConfig.instance;
  if _config.autoSpeed then
  begin
    if cdrom <> nil then
    begin
      pauseGameMusic(temp);
    end
    else
    begin
      if temp then
      begin
        Mix_PauseMusic;
      end
      else
      begin
        Mix_ResumeMusic;
      end;
    end;
  end;

end;

procedure AudioSDLMixer.playSound(_type: SoundType; pos: array of Single; age: Integer);
var
  _config: Config;
  i: Integer;
begin
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    Mix_PlayChannel(-1, sounds[Integer(_type)], 0);
  end;
end;

procedure AudioSDLMixer.setMusicMode(temp: SoundType);
var
  _config: Config;
  i: Integer;
begin
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    inherited setMusicMode(temp);
    //setMusicMode(temp);
    case temp of
      MusicGame:
        begin
          //if cdrom = nil then
          //begin
          //  Mix_HaltChannel(0);
          //end
          //else
          //begin
            Mix_PlayChannel(0, sounds[Integer(temp)], -1);
          //end;
        end;
      MusicMenu:
        begin
          Mix_PlayChannel(0, sounds[Integer(temp)], -1);
        end;
    else
      if cdrom = nil then
      begin
        Mix_HaltChannel(0);
      end
      else
      begin
        Mix_PlayChannel(0, sounds[Integer(temp)], -1);
      end;
    end;
  end;
end;

procedure AudioSDLMixer.setMusicVolume(temp: Single);
var
  _config: Config;
begin
  inherited setMusicVolume(temp);
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    Mix_Volume(0, Round(MIX_MAX_VOLUME * temp));
  end;
end;

procedure AudioSDLMixer.setSoundVolume(temp: Single);
var
  _config: Config;
  i: Integer;
begin
  setMusicVolume(temp);
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    for i := 1 to MIX_CHANNELS - 1 do
    begin
      Mix_Volume(i, Round(MIX_MAX_VOLUME * temp));
    end;
  end;

end;

procedure AudioSDLMixer.stopMusic;
var
  _config: Config;
begin
  _config := uniConfig.instance;
  if _config.audioEnabled then
  begin
    inherited stopMusic;
    Mix_HaltChannel(0);
  end;
end;

end.

